package com.baishancloud.log.common.util


import com.baishancloud.log.common.entity.ServerCacheGroupEntity
import org.slf4j.{Logger, LoggerFactory}

import java.sql._
import java.util.{Timer, TimerTask}
import scala.collection.mutable
import scala.util.control.Breaks.{break, breakable}

class DimMessageFetch

/**
 * 通过doris的dim表来获取各种信息<br>
 * 内部使用定时器定时从starRocks表中获取，类内部存储了最新的数据，各获取函数均为内存访问，不存在高并发性能问题<br>
 * 已过时，推荐使用[[ExternalDataFetchUtil]]。该实现中只是简单对缓存数据做了内存缓存，在任务多TM运行的情况下，还是会发生高并发问题，尤其是访问HTTP接口。
 *
 * @author ziqiang.wang 
 * @date 2021/12/8 17:28
 */
@deprecated
object DimMessageFetch extends Serializable {

  private val LOGGER: Logger = LoggerFactory.getLogger(classOf[DimMessageFetch])

  /**
   * 内部各缓存map从starRocks表更新数据时间间隔，10分钟
   */
  private val innerMapUpdateInterval: Long = 10 * 60 * 1000

  //***************************************************************************starRocks***************************************************************************

  private val driverName: String = "com.mysql.jdbc.Driver"
  private val cjDriverName: String = "com.mysql.cj.jdbc.Driver"
  private val jdbcUrl = "jdbc:mysql://10.104.7.41:9030"
  private val username = "portal"
  private val password = "portal@Baishancloud#1qaz"
  private var connection: Connection = _

  {
    //加载驱动类
    try {
      Class.forName(cjDriverName)
      LOGGER.info(s"成功加载驱动：$driverName")
    }
    catch {
      case _: ClassNotFoundException => {
        Class.forName(driverName)
        LOGGER.info(s"成功加载驱动：$cjDriverName")
      }
    }
  }

  /**
   * 获取连接
   */
  private def getConnection: Connection = {
    if (connection == null || !connection.isValid(5)) {
      connection = DriverManager.getConnection(jdbcUrl, username, password)

    }
    connection
  }

  /**
   * 关闭连接
   */
  private def closeConnection(): Unit = {
    if (connection == null) return
    try {
      connection.close()
    }
    catch {
      case e: SQLException => LOGGER.error("JDBC连接关闭失败", e)
    } finally {
      connection = null
    }
  }


  //***************************************************************************获取所有最新域名id信息***************************************************************************
  /**
   * 内部domainIdInnerMap表，由Timer定时器定时更新其内容，其他任务获取内容时，从该map表直接获取即可，无需每次查询starRocks表。
   */
  private val domainIdInnerMap: mutable.Map[String, Int] = mutable.Map[String, Int]()
  /**
   * 内部domainIdInnerMap更新sql语句
   */
  private val domainIdInnerMapSql: String = "select name, id from cache_log.dim_domain order by id limit ? offset ?;"

  /**
   * 从starRocks中查询域名和id信息，并更新到内部域名id信息表中
   */
  private def domainIdInnerMapUpdate(): Unit = {
    LOGGER.info("开始更新domainIdInner表")
    val connection: Connection = getConnection
    val prepareStatement: PreparedStatement = connection.prepareStatement(domainIdInnerMapSql)
    prepareStatement.setInt(1, 10000)
    prepareStatement.setInt(2, 0)
    var selectTimes: Int = 1
    var total: Int = 0
    breakable(
      //开始更新内部domainIdInnerMap表，获取同步锁，防止读取到更新时的数据
      domainIdInnerMap.synchronized {
        domainIdInnerMap.clear()
        //如果select查询获取到的数据量为10000条，则说明表中可能还有数据，则需要再次获取，直到获取到的数量小于10000条。
        while (true) {
          val rs: ResultSet = prepareStatement.executeQuery()
          while (rs.next()) {
            domainIdInnerMap.put(rs.getString(1), rs.getInt(2))
            total += 1
          }
          rs.close()
          if (total % 10000 == 0) {
            prepareStatement.setInt(2, 10000 * selectTimes)
            selectTimes += 1
          } else if (total % 10000 != 0) {
            break()
          }
        }
      }
    )
    if (domainIdInnerMap.isEmpty) {
      LOGGER.error(s"更新domainIdInnerMap表失败，查询信息为：${prepareStatement.toString}")
    } else {
      LOGGER.info(s"更新domainIdInnerMap表完成，表数据量：${domainIdInnerMap.size}")
    }
    prepareStatement.close()
    closeConnection()
  }

  /**
   * 内部domainIdInnerMap是否已经初始化并启动定时线程
   */
  private var domainIdInnerMapInitAndTimerFlag: Boolean = false

  /**
   * 更新内部域名id信息表，并触发定时更新<br>
   * 10分钟更新一次
   */
  private def domainIdInnerMapInitAndTimer(): Unit = {
    LOGGER.info("初始化domainIdInnerMap表")
    domainIdInnerMapUpdate()
    //初始化完毕后，将初始化标识设置为true
    domainIdInnerMapInitAndTimerFlag = true
    new Timer("定时更新domainIdInnerMap表", true).scheduleAtFixedRate(new TimerTask {
      override def run(): Unit = domainIdInnerMapUpdate()
    }, innerMapUpdateInterval, innerMapUpdateInterval)
  }

  /**
   * 从starRocks表中获取所有域名和id对应信息
   */
  def fetchDomainIdAll(domainId: mutable.Map[String, Int]): Unit = {
    //使用domainIdInnerMap同步锁，防止同时读写造成数据安全问题
    domainIdInnerMap.synchronized {
      if (domainIdInnerMap.nonEmpty) {
        domainId.clear()
        domainIdInnerMap.foreach(t => domainId.put(t._1, t._2))
      } else if (!domainIdInnerMapInitAndTimerFlag) {
        //如果内部domainIdInnerMap为空，则对内部domainIdInnerMap进行初始化并启动定时线程
        domainIdInnerMapInitAndTimer()
        if (domainIdInnerMap.nonEmpty) {
          domainId.clear()
          domainIdInnerMap.foreach(t => domainId.put(t._1, t._2))
        }
      }
    }
  }



  //***************************************************************************获取指定账户最新域名id信息***************************************************************************
  /**
   * 内部accountDomainIdInnerMap表，由Timer定时器定时更新其内容，其他任务获取内容时，从该map表直接获取即可，无需每次查询starRocks表。
   */
  private val accountDomainIdInnerMap: mutable.Map[String, Int] = mutable.Map[String, Int]()
  // 内部accountDomainIdInnerMap更新sql语句
  private val accountDomainIdInnerMapSqlPre: String = "select name, id from cache_log.dim_domain where user_id in ( select id from cache_log.dim_user where name in ( "
  private val accountDomainIdInnerMapSqlSuf: String = " ) ) order by id limit ? offset ? ;"
  private var accountDomainIdInnerMapSql: String = ""


  /**
   * 从starRocks表中查询指定账户域名和id信息，并更新到内部账户域名id信息表中
   */
  private def accountDomainIdInnerMapUpdate(): Unit = {
    LOGGER.info("开始更新accountDomainIdInnerMap表")
    val connection: Connection = getConnection
    val prepareStatement: PreparedStatement = connection.prepareStatement(accountDomainIdInnerMapSql)
    prepareStatement.setInt(1, 10000)
    prepareStatement.setInt(2, 0)
    var selectTimes: Int = 1
    var total: Int = 0
    breakable(
      //开始更新内部domainIdInnerMap表，获取同步锁，防止读取到更新时的数据
      accountDomainIdInnerMap.synchronized {
        accountDomainIdInnerMap.clear()
        //如果select查询获取到的数据量为10000条，则说明表中可能还有数据，则需要再次获取，直到获取到的数量小于10000条。
        while (true) {
          val rs: ResultSet = prepareStatement.executeQuery()
          while (rs.next()) {
            accountDomainIdInnerMap.put(rs.getString(1), rs.getInt(2))
            total += 1
          }
          rs.close()
          if (total % 10000 == 0) {
            prepareStatement.setInt(2, 10000 * selectTimes)
            selectTimes += 1
          } else if (total % 10000 != 0) {
            break()
          }
        }
      }
    )
    if (accountDomainIdInnerMap.isEmpty) {
      LOGGER.error(s"更新accountDomainIdInner表失败，查询信息为：${prepareStatement.toString}")
    } else {
      LOGGER.info(s"更新accountDomainIdInner表完成，表数据量：${accountDomainIdInnerMap.size}")
    }
    prepareStatement.close()
    closeConnection()
  }

  /**
   * 内部accountDomainIdInnerMap是否已经初始化并启动定时线程
   */
  private var accountDomainIdInnerMapInitAndTimerFlag: Boolean = false

  /**
   * 更新内部账户域名id信息表，并触发定时更新<br>
   * 10分钟更新一次
   *
   * @param accounts 要获取域名和id信息的账户，支持多账户，使用英文逗号分隔
   */
  private def accountDomainIdInnerMapInitAndTimer(accounts: String): Unit = {
    LOGGER.info("初始化accountDomainIdInner表")
    var sqlMiddle: String = ""
    accounts.split(",").foreach(account => sqlMiddle += ("'" + account.trim + "'" + ", "))
    sqlMiddle = sqlMiddle.substring(0, sqlMiddle.length - 2)
    accountDomainIdInnerMapSql = accountDomainIdInnerMapSqlPre + sqlMiddle + accountDomainIdInnerMapSqlSuf
    accountDomainIdInnerMapUpdate()
    //初始化完毕后，将初始化标识设置为true
    accountDomainIdInnerMapInitAndTimerFlag = true
    new Timer("定时更新accountDomainIdInnerMap表", true).scheduleAtFixedRate(new TimerTask {
      override def run(): Unit = accountDomainIdInnerMapUpdate()
    }, innerMapUpdateInterval, innerMapUpdateInterval)
  }

  /**
   * 从starRocks表中获取指定账户域名和id对应信息
   *
   * @param accounts 要获取域名和id信息的账户，支持多账户
   */
  def fetchAccountDomainId(accounts: String, accountDomainId: mutable.Map[String, Int]): Unit = {
    //使用accountDomainIdInnerMap同步锁，防止同时读写造成数据安全问题
    accountDomainIdInnerMap.synchronized {
      if (accountDomainIdInnerMap.nonEmpty) {
        accountDomainId.clear()
        accountDomainIdInnerMap.foreach(t => accountDomainId.put(t._1, t._2))
      } else if (!accountDomainIdInnerMapInitAndTimerFlag) {
        //如果内部accountDomainIdInnerMap为空，则对内部accountDomainIdInnerMap行初始化并启动定时线程
        accountDomainIdInnerMapInitAndTimer(accounts)
        if (accountDomainIdInnerMap.nonEmpty) {
          accountDomainId.clear()
          accountDomainIdInnerMap.foreach(t => accountDomainId.put(t._1, t._2))
        }
      }
    }
  }




  //***************************************************************************获取ip对应cache组的code信息***************************************************************************
  /**
   * 内部ipCacheGroupCode表，由Timer定时器定时更新其内容，其他任务获取内容时，从该map表直接获取即可，无需每次查询starRocks表。<br>
   * key:IP地址、value:cache组信息
   */
  private val ipCacheGroupCodeInnerMap: mutable.Map[String, ServerCacheGroupEntity] = mutable.Map[String, ServerCacheGroupEntity]()
  /**
   * 内部ipCacheGroupCodeInnerMap更新sql语句
   */
  private val ipCacheGroupCodeInnerMapSql: String = "select a.ip, b.id, b.code from cache_log.dim_cache as a join cache_log.dim_cache_group as b on a.cache_group = b.id order by a.ip limit ? offset ?;"

  /**
   * 从starRocks表中查询ip对应cache组的code信息，并更新到内部ip对应cache组的code信息表中
   */
  private def ipCacheGroupCodeInnerMapUpdate(): Unit = {
    LOGGER.info("开始更新ipCacheGroupCodeInner表")
    val connection: Connection = getConnection
    val prepareStatement: PreparedStatement = connection.prepareStatement(ipCacheGroupCodeInnerMapSql)
    prepareStatement.setInt(1, 10000)
    prepareStatement.setInt(2, 0)
    var selectTimes: Int = 1
    var total: Int = 0
    breakable(
      //开始更新内部ipCacheGroupCodeInnerMap表，获取同步锁，防止读取到更新时的数据
      ipCacheGroupCodeInnerMap.synchronized {
        ipCacheGroupCodeInnerMap.clear()
        //如果select查询获取到的数据量为10000条，则说明表中可能还有数据，则需要再次获取，直到获取到的数量小于10000条。
        while (true) {
          val rs: ResultSet = prepareStatement.executeQuery()
          while (rs.next()) {
            ipCacheGroupCodeInnerMap.put(rs.getString(1), ServerCacheGroupEntity(0, "", "", rs.getInt(2), 0, "", rs.getString(3)))
            total += 1
          }
          rs.close()
          if (total % 10000 == 0) {
            prepareStatement.setInt(2, 10000 * selectTimes)
            selectTimes += 1
          } else if (total % 10000 != 0) {
            break()
          }
        }
      }
    )
    if (ipCacheGroupCodeInnerMap.isEmpty) {
      LOGGER.error(s"更新ipCacheGroupCodeInner表失败，查询信息为：${prepareStatement.toString}")
    } else {
      LOGGER.info(s"更新ipCacheGroupCodeInner表完成，表数据量：${ipCacheGroupCodeInnerMap.size}")
    }
    prepareStatement.close()
  }

  /**
   * 内部ipCacheGroupCodeInnerMap是否已经初始化并启动定时线程
   */
  private var ipCacheGroupCodeInnerMapInitAndTimerFlag: Boolean = false

  /**
   * 更新内部账户域名id信息表，并触发定时更新<br>
   * 10分钟更新一次
   */
  private def ipCacheGroupCodeInnerMapInitAndTimer(): Unit = {
    LOGGER.info("初始化ipCacheGroupCodeInner表")
    ipCacheGroupCodeInnerMapUpdate()
    //初始化完毕后，将初始化标识设置为true
    ipCacheGroupCodeInnerMapInitAndTimerFlag = true
    new Timer("定时更新ipCacheGroupCodeInnerMap表", true).scheduleAtFixedRate(new TimerTask {
      override def run(): Unit = ipCacheGroupCodeInnerMapUpdate()
    }, innerMapUpdateInterval, innerMapUpdateInterval)
  }

  /**
   * 从starRocks表中获取ip对应cache组的code信息
   */
  def fetchIpCacheGroupCode(ipCacheGroupCode: mutable.Map[String, ServerCacheGroupEntity]): Unit = {
    //使用ipCacheGroupCodeInnerMap同步锁，防止同时读写造成数据安全问题
    ipCacheGroupCodeInnerMap.synchronized {
      if (ipCacheGroupCodeInnerMap.nonEmpty) {
        ipCacheGroupCode.clear()
        ipCacheGroupCodeInnerMap.foreach(t => ipCacheGroupCode.put(t._1, t._2))
      } else if (!ipCacheGroupCodeInnerMapInitAndTimerFlag) {
        //如果内部ipCacheGroupCodeInnerMap为空，则对内部ipCacheGroupCodeInnerMap进行初始化并启动定时线程
        ipCacheGroupCodeInnerMapInitAndTimer()
        if (ipCacheGroupCodeInnerMap.nonEmpty) {
          ipCacheGroupCode.clear()
          ipCacheGroupCodeInnerMap.foreach(t => ipCacheGroupCode.put(t._1, t._2))
        }
      }
    }
  }



  //***************************************************************************获取所有最新国家id信息***************************************************************************
  /**
   * 内部countryIdInnerMap表，由Timer定时器定时更新其内容，其他任务获取内容时，从该map表直接获取即可，无需每次查询starRocks表。
   */
  private val countryIdInnerMap: mutable.Map[String, Int] = mutable.Map[String, Int]()
  /**
   * 内部countryIdInnerMap更新sql语句
   */
  private val countryIdInnerMapSql: String = "select name, id from cache_log.dim_country order by id limit ? offset ?;"

  /**
   * 从starRocks中查询国家和id信息，并更新到内部域名id信息表中
   */
  private def countryIdInnerMapUpdate(): Unit = {
    LOGGER.info("开始更新countryIdInnerMap表")
    val connection: Connection = getConnection
    val prepareStatement: PreparedStatement = connection.prepareStatement(countryIdInnerMapSql)
    prepareStatement.setInt(1, 10000)
    prepareStatement.setInt(2, 0)
    var selectTimes: Int = 1
    var total: Int = 0
    breakable(
      //开始更新内部countryIdInnerMap表，获取同步锁，防止读取到更新时的数据
      countryIdInnerMap.synchronized {
        countryIdInnerMap.clear()
        //如果select查询获取到的数据量为10000条，则说明表中可能还有数据，则需要再次获取，直到获取到的数量小于10000条。
        while (true) {
          val rs: ResultSet = prepareStatement.executeQuery()
          while (rs.next()) {
            countryIdInnerMap.put(rs.getString(1), rs.getInt(2))
            total += 1
          }
          rs.close()
          if (total % 10000 == 0) {
            prepareStatement.setInt(2, 10000 * selectTimes)
            selectTimes += 1
          } else if (total % 10000 != 0) {
            break()
          }
        }
      }
    )
    if (countryIdInnerMap.isEmpty) {
      LOGGER.error(s"更新countryIdInnerMap表失败，查询信息为：${prepareStatement.toString}")
    } else {
      LOGGER.info(s"更新countryIdInnerMap表完成，表数据量：${countryIdInnerMap.size}")
    }
    prepareStatement.close()
  }

  /**
   * 内部countryIdInnerMap是否已经初始化并启动定时线程
   */
  private var countryIdInnerMapInitAndTimerFlag: Boolean = false

  /**
   * 更新内部域名id信息表，并触发定时更新<br>
   * 10分钟更新一次
   */
  private def countryIdInnerMapInitAndTimer(): Unit = {
    LOGGER.info("初始化countryIdInnerMap表")
    countryIdInnerMapUpdate()
    //初始化完毕后，将初始化标识设置为true
    countryIdInnerMapInitAndTimerFlag = true
    new Timer("定时更新countryIdInnerMap表", true).scheduleAtFixedRate(new TimerTask {
      override def run(): Unit = countryIdInnerMapUpdate()
    }, innerMapUpdateInterval, innerMapUpdateInterval)
  }

  /**
   * 从starRocks表中获取所有国家和id对应信息
   */
  def fetchCountryIdAll(countryId: mutable.Map[String, Int]): Unit = {
    //使用countryIdInnerMap同步锁，防止同时读写造成数据安全问题
    countryIdInnerMap.synchronized {
      if (countryIdInnerMap.nonEmpty) {
        countryId.clear()
        countryIdInnerMap.foreach(t => countryId.put(t._1, t._2))
      } else if (!countryIdInnerMapInitAndTimerFlag) {
        //如果内部countryIdInnerMap为空，则对内部countryIdInnerMap进行初始化并启动定时线程
        countryIdInnerMapInitAndTimer()
        if (countryIdInnerMap.nonEmpty) {
          countryId.clear()
          countryIdInnerMap.foreach(t => countryId.put(t._1, t._2))
        }
      }
    }
  }



  //***************************************************************************获取所有最新省份id信息***************************************************************************
  /**
   * 内部provinceIdInnerMap表，由Timer定时器定时更新其内容，其他任务获取内容时，从该map表直接获取即可，无需每次查询starRocks表。
   */
  private val provinceIdInnerMap: mutable.Map[String, Int] = mutable.Map[String, Int]()
  /**
   * 内部provinceIdInnerMap更新sql语句
   */
  private val provinceIdInnerMapSql: String = "select name, id from cache_log.dim_province order by id limit ? offset ?;"

  /**
   * 从starRocks中查询省份和id信息，并更新到内部域名id信息表中
   */
  private def provinceIdInnerMapUpdate(): Unit = {
    LOGGER.info("开始更新provinceIdInnerMap表")
    val connection: Connection = getConnection
    val prepareStatement: PreparedStatement = connection.prepareStatement(provinceIdInnerMapSql)
    prepareStatement.setInt(1, 10000)
    prepareStatement.setInt(2, 0)
    var selectTimes: Int = 1
    var total: Int = 0
    breakable(
      //开始更新内部provinceIdInnerMap表，获取同步锁，防止读取到更新时的数据
      provinceIdInnerMap.synchronized {
        provinceIdInnerMap.clear()
        //如果select查询获取到的数据量为10000条，则说明表中可能还有数据，则需要再次获取，直到获取到的数量小于10000条。
        while (true) {
          val rs: ResultSet = prepareStatement.executeQuery()
          while (rs.next()) {
            provinceIdInnerMap.put(rs.getString(1), rs.getInt(2))
            total += 1
          }
          rs.close()
          if (total % 10000 == 0) {
            prepareStatement.setInt(2, 10000 * selectTimes)
            selectTimes += 1
          } else if (total % 10000 != 0) {
            break()
          }
        }
      }
    )
    if (provinceIdInnerMap.isEmpty) {
      LOGGER.error(s"更新provinceIdInnerMap表失败，查询信息为：${prepareStatement.toString}")
    } else {
      LOGGER.info(s"更新provinceIdInnerMap表完成，表数据量：${provinceIdInnerMap.size}")
    }
    prepareStatement.close()
    closeConnection()
  }

  /**
   * 内部provinceIdInnerMap是否已经初始化并启动定时线程
   */
  private var provinceIdInnerMapInitAndTimerFlag: Boolean = false

  /**
   * 更新内部域名id信息表，并触发定时更新<br>
   * 10分钟更新一次
   */
  private def provinceIdInnerMapInitAndTimer(): Unit = {
    LOGGER.info("初始化provinceIdInnerMap表")
    provinceIdInnerMapUpdate()
    //初始化完毕后，将初始化标识设置为true
    provinceIdInnerMapInitAndTimerFlag = true
    new Timer("定时更新provinceIdInnerMap表", true).scheduleAtFixedRate(new TimerTask {
      override def run(): Unit = provinceIdInnerMapUpdate()
    }, innerMapUpdateInterval, innerMapUpdateInterval)
  }

  /**
   * 从starRocks表中获取所有国家和id对应信息
   */
  def fetchProvinceIdAll(provinceId: mutable.Map[String, Int]): Unit = {
    //使用provinceIdInnerMap同步锁，防止同时读写造成数据安全问题
    provinceIdInnerMap.synchronized {
      if (provinceIdInnerMap.nonEmpty) {
        provinceId.clear()
        provinceIdInnerMap.foreach(t => provinceId.put(t._1, t._2))
      } else if (!provinceIdInnerMapInitAndTimerFlag) {
        //如果内部provinceIdInnerMap为空，则对内部provinceIdInnerMap进行初始化并启动定时线程
        provinceIdInnerMapInitAndTimer()
        if (provinceIdInnerMap.nonEmpty) {
          provinceId.clear()
          provinceIdInnerMap.foreach(t => provinceId.put(t._1, t._2))
        }
      }
    }
  }



  //***************************************************************************获取所有最新运营商id信息***************************************************************************
  /**
   * 内部ispIdInnerMap表，由Timer定时器定时更新其内容，其他任务获取内容时，从该map表直接获取即可，无需每次查询starRocks表。
   */
  private val ispIdInnerMap: mutable.Map[String, Int] = mutable.Map[String, Int]()
  /**
   * 内部ispIdInnerMap更新sql语句
   */
  private val ispIdInnerMapSql: String = "select name, id from cache_log.dim_isp order by id limit ? offset ?;"

  /**
   * 从starRocks中查询运营商和id信息，并更新到内部域名id信息表中
   */
  private def ispIdInnerMapUpdate(): Unit = {
    LOGGER.info("开始更新ispIdInnerMap表")
    val connection: Connection = getConnection
    val prepareStatement: PreparedStatement = connection.prepareStatement(ispIdInnerMapSql)
    prepareStatement.setInt(1, 10000)
    prepareStatement.setInt(2, 0)
    var selectTimes: Int = 1
    var total: Int = 0
    breakable(
      //开始更新内部ispIdInnerMap表，获取同步锁，防止读取到更新时的数据
      ispIdInnerMap.synchronized {
        ispIdInnerMap.clear()
        //如果select查询获取到的数据量为10000条，则说明表中可能还有数据，则需要再次获取，直到获取到的数量小于10000条。
        while (true) {
          val rs: ResultSet = prepareStatement.executeQuery()
          while (rs.next()) {
            ispIdInnerMap.put(rs.getString(1), rs.getInt(2))
            total += 1
          }
          rs.close()
          if (total % 10000 == 0) {
            prepareStatement.setInt(2, 10000 * selectTimes)
            selectTimes += 1
          } else if (total % 10000 != 0) {
            break()
          }
        }
      }
    )
    if (ispIdInnerMap.isEmpty) {
      LOGGER.error(s"更新ispIdInnerMap表失败，查询信息为：${prepareStatement.toString}")
    } else {
      LOGGER.info(s"更新ispIdInnerMap表完成，表数据量：${ispIdInnerMap.size}")
    }
    prepareStatement.close()
    closeConnection()
  }

  /**
   * 内部ispIdInnerMap是否已经初始化并启动定时线程
   */
  private var ispIdInnerMapInitAndTimerFlag: Boolean = false

  /**
   * 更新内部域名id信息表，并触发定时更新<br>
   * 10分钟更新一次
   */
  private def ispIdInnerMapInitAndTimer(): Unit = {
    LOGGER.info("初始化ispIdInnerMap表")
    ispIdInnerMapUpdate()
    //初始化完毕后，将初始化标识设置为true
    ispIdInnerMapInitAndTimerFlag = true
    new Timer("定时更新ispIdInnerMap表", true).scheduleAtFixedRate(new TimerTask {
      override def run(): Unit = ispIdInnerMapUpdate()
    }, innerMapUpdateInterval, innerMapUpdateInterval)
  }

  /**
   * 从starRocks表中获取所有isp和id对应信息
   */
  def fetchIspIdAll(ispId: mutable.Map[String, Int]): Unit = {
    //使用ispIdInnerMap同步锁，防止同时读写造成数据安全问题
    ispIdInnerMap.synchronized {
      if (ispIdInnerMap.nonEmpty) {
        ispId.clear()
        ispIdInnerMap.foreach(t => ispId.put(t._1, t._2))
      } else if (!ispIdInnerMapInitAndTimerFlag) {
        //如果内部ispIdInnerMap为空，则对内部ispIdInnerMap进行初始化并启动定时线程
        ispIdInnerMapInitAndTimer()
        if (ispIdInnerMap.nonEmpty) {
          ispId.clear()
          ispIdInnerMap.foreach(t => ispId.put(t._1, t._2))
        }
      }
    }
  }

}
